/**
 ******************************************************************************
 * @file           : bsp_can.h
 * @brief          : CAN Driver Header File (STM32H7xx)
 ******************************************************************************
 * @attention
 *
 * CAN总线驱动程序头文件
 * 提供CAN通信接口
 * 支持标准帧和扩展帧、过滤器配置
 *
 ******************************************************************************
 */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __BSP_CAN_H
#define __BSP_CAN_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>

/* Exported types ------------------------------------------------------------*/
/**
 * @brief CAN错误码枚举
 */
typedef enum
{
    CAN_OK = 0,                 /*!< 成功 */
    CAN_ERROR_PARAM,            /*!< 参数错误 */
    CAN_ERROR_TIMEOUT,          /*!< 超时错误 */
    CAN_ERROR_BUSY,             /*!< 总线忙 */
    CAN_ERROR_FULL,             /*!< 缓冲区满 */
    CAN_ERROR_EMPTY,            /*!< 缓冲区空 */
    CAN_ERROR_HAL               /*!< HAL库错误 */
} CAN_Error_e;

/**
 * @brief CAN消息结构体
 */
typedef struct
{
    uint32_t id;                /*!< CAN ID(标准帧11位或扩展帧29位) */
    uint8_t ide;                /*!< 帧类型：0=标准帧, 1=扩展帧 */
    uint8_t rtr;                /*!< 帧格式：0=数据帧, 1=远程帧 */
    uint8_t dlc;                /*!< 数据长度(0-8) */
    uint8_t data[8];            /*!< 数据 */
} CAN_Message_t;

/**
 * @brief CAN状态枚举
 */
typedef enum
{
    CAN_STATE_IDLE = 0,         /*!< 空闲状态 */
    CAN_STATE_BUSY,             /*!< 忙状态 */
    CAN_STATE_TX,               /*!< 发送状态 */
    CAN_STATE_RX,               /*!< 接收状态 */
    CAN_STATE_ERROR             /*!< 错误状态 */
} CAN_State_e;

/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/

/**
 * @brief       CAN初始化
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        初始化CAN外设和相关GPIO
 */
void can_init(void);

/**
 * @brief       CAN反初始化
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        关闭CAN外设
 */
void can_deinit(void);

/**
 * @brief       配置过滤器
 *
 * @param[in]   id - 过滤器ID
 * @param[in]   mask - 过滤器掩码
 *
 * @retval      CAN_Error_e - 错误码
 *
 * @note        配置硬件过滤器
 */
CAN_Error_e can_filter_config(uint32_t id, uint32_t mask);

/**
 * @brief       禁用过滤器
 *
 * @param       无
 *
 * @retval      CAN_Error_e - 错误码
 *
 * @note        禁用硬件过滤器，接收所有消息
 */
CAN_Error_e can_filter_disable(void);

/**
 * @brief       发送CAN消息
 *
 * @param[in]   msg - CAN消息结构体指针
 *
 * @retval      CAN_Error_e - 错误码
 *
 * @note        发送一条CAN消息
 */
CAN_Error_e can_send(const CAN_Message_t *msg);

/**
 * @brief       发送标准帧
 *
 * @param[in]   id - 标准ID(11位)
 * @param[in]   data - 数据指针
 * @param[in]   len - 数据长度(0-8)
 *
 * @retval      CAN_Error_e - 错误码
 *
 * @note        发送标准帧数据
 */
CAN_Error_e can_send_std(uint32_t id, const uint8_t *data, uint8_t len);

/**
 * @brief       发送扩展帧
 *
 * @param[in]   id - 扩展ID(29位)
 * @param[in]   data - 数据指针
 * @param[in]   len - 数据长度(0-8)
 *
 * @retval      CAN_Error_e - 错误码
 *
 * @note        发送扩展帧数据
 */
CAN_Error_e can_send_ext(uint32_t id, const uint8_t *data, uint8_t len);

/**
 * @brief       接收CAN消息
 *
 * @param[out]  msg - CAN消息结构体指针
 *
 * @retval      CAN_Error_e - 错误码
 *
 * @note        接收一条CAN消息
 */
CAN_Error_e can_receive(CAN_Message_t *msg);

/**
 * @brief       获取可用消息数
 *
 * @param       无
 *
 * @retval      uint16_t - 可用消息数
 *
 * @note        返回接收缓冲区中的消息数
 */
uint16_t can_available(void);

/**
 * @brief       获取CAN状态
 *
 * @param       无
 *
 * @retval      CAN_State_e - CAN状态
 *
 * @note        无
 */
CAN_State_e can_get_state(void);

/**
 * @brief       检查总线关闭
 *
 * @param       无
 *
 * @retval      uint8_t - 1=总线关闭, 0=正常
 *
 * @note        检查CAN总线是否关闭
 */
uint8_t can_is_bus_off(void);

/**
 * @brief       打印CAN状态
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        用于调试，打印CAN状态信息
 */
void can_print_status(void);

/**
 * @brief       打印CAN消息
 *
 * @param[in]   msg - CAN消息结构体指针
 *
 * @retval      无
 *
 * @note        用于调试，打印CAN消息内容
 */
void can_print_message(const CAN_Message_t *msg);

#ifdef __cplusplus
}
#endif

#endif /* __BSP_CAN_H */
